//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension EC2InstanceConnect {
    // MARK: Enums

    // MARK: Shapes

    public struct SendSSHPublicKeyRequest: AWSEncodableShape {
        /// The Availability Zone in which the EC2 instance was launched.
        public let availabilityZone: String?
        /// The ID of the EC2 instance.
        public let instanceId: String
        /// The OS user on the EC2 instance for whom the key can be used to authenticate.
        public let instanceOSUser: String
        /// The public key material. To use the public key, you must have the matching private key.
        public let sshPublicKey: String

        @inlinable
        public init(availabilityZone: String? = nil, instanceId: String, instanceOSUser: String, sshPublicKey: String) {
            self.availabilityZone = availabilityZone
            self.instanceId = instanceId
            self.instanceOSUser = instanceOSUser
            self.sshPublicKey = sshPublicKey
        }

        public func validate(name: String) throws {
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, max: 32)
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, min: 6)
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, pattern: "^(\\w+-){2,3}\\d+\\w+$")
            try self.validate(self.instanceId, name: "instanceId", parent: name, max: 32)
            try self.validate(self.instanceId, name: "instanceId", parent: name, min: 10)
            try self.validate(self.instanceId, name: "instanceId", parent: name, pattern: "^i-[a-f0-9]+$")
            try self.validate(self.instanceOSUser, name: "instanceOSUser", parent: name, max: 32)
            try self.validate(self.instanceOSUser, name: "instanceOSUser", parent: name, min: 1)
            try self.validate(self.instanceOSUser, name: "instanceOSUser", parent: name, pattern: "^(^[A-Za-z_][A-Za-z0-9\\@\\._-]{0,30}[A-Za-z0-9\\$_-]?$)|(^(?=.{2,32}$)[0-9]{1,32}[A-Za-z\\@\\._-][A-Za-z0-9\\@\\._-]*[A-Za-z0-9\\$_-]?$)$")
            try self.validate(self.sshPublicKey, name: "sshPublicKey", parent: name, max: 4096)
            try self.validate(self.sshPublicKey, name: "sshPublicKey", parent: name, min: 80)
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case instanceId = "InstanceId"
            case instanceOSUser = "InstanceOSUser"
            case sshPublicKey = "SSHPublicKey"
        }
    }

    public struct SendSSHPublicKeyResponse: AWSDecodableShape {
        /// The ID of the request. Please provide this ID when contacting AWS Support for assistance.
        public let requestId: String?
        /// Is true if the request succeeds and an error otherwise.
        public let success: Bool?

        @inlinable
        public init(requestId: String? = nil, success: Bool? = nil) {
            self.requestId = requestId
            self.success = success
        }

        private enum CodingKeys: String, CodingKey {
            case requestId = "RequestId"
            case success = "Success"
        }
    }

    public struct SendSerialConsoleSSHPublicKeyRequest: AWSEncodableShape {
        /// The ID of the EC2 instance.
        public let instanceId: String
        /// The serial port of the EC2 instance. Currently only port 0 is supported. Default: 0
        public let serialPort: Int?
        /// The public key material. To use the public key, you must have the matching private key. For information about the supported key formats and lengths, see Requirements for key pairs in the Amazon EC2 User Guide.
        public let sshPublicKey: String

        @inlinable
        public init(instanceId: String, serialPort: Int? = nil, sshPublicKey: String) {
            self.instanceId = instanceId
            self.serialPort = serialPort
            self.sshPublicKey = sshPublicKey
        }

        public func validate(name: String) throws {
            try self.validate(self.instanceId, name: "instanceId", parent: name, max: 32)
            try self.validate(self.instanceId, name: "instanceId", parent: name, min: 10)
            try self.validate(self.instanceId, name: "instanceId", parent: name, pattern: "^i-[a-f0-9]+$")
            try self.validate(self.serialPort, name: "serialPort", parent: name, max: 0)
            try self.validate(self.serialPort, name: "serialPort", parent: name, min: 0)
            try self.validate(self.sshPublicKey, name: "sshPublicKey", parent: name, max: 4096)
            try self.validate(self.sshPublicKey, name: "sshPublicKey", parent: name, min: 80)
        }

        private enum CodingKeys: String, CodingKey {
            case instanceId = "InstanceId"
            case serialPort = "SerialPort"
            case sshPublicKey = "SSHPublicKey"
        }
    }

    public struct SendSerialConsoleSSHPublicKeyResponse: AWSDecodableShape {
        /// The ID of the request. Please provide this ID when contacting AWS Support for assistance.
        public let requestId: String?
        /// Is true if the request succeeds and an error otherwise.
        public let success: Bool?

        @inlinable
        public init(requestId: String? = nil, success: Bool? = nil) {
            self.requestId = requestId
            self.success = success
        }

        private enum CodingKeys: String, CodingKey {
            case requestId = "RequestId"
            case success = "Success"
        }
    }
}

// MARK: - Errors

/// Error enum for EC2InstanceConnect
public struct EC2InstanceConnectErrorType: AWSErrorType {
    enum Code: String {
        case authException = "AuthException"
        case ec2InstanceNotFoundException = "EC2InstanceNotFoundException"
        case ec2InstanceStateInvalidException = "EC2InstanceStateInvalidException"
        case ec2InstanceTypeInvalidException = "EC2InstanceTypeInvalidException"
        case ec2InstanceUnavailableException = "EC2InstanceUnavailableException"
        case invalidArgsException = "InvalidArgsException"
        case serialConsoleAccessDisabledException = "SerialConsoleAccessDisabledException"
        case serialConsoleSessionLimitExceededException = "SerialConsoleSessionLimitExceededException"
        case serialConsoleSessionUnavailableException = "SerialConsoleSessionUnavailableException"
        case serialConsoleSessionUnsupportedException = "SerialConsoleSessionUnsupportedException"
        case serviceException = "ServiceException"
        case throttlingException = "ThrottlingException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize EC2InstanceConnect
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Either your AWS credentials are not valid or you do not have access to the EC2 instance.
    public static var authException: Self { .init(.authException) }
    /// The specified instance was not found.
    public static var ec2InstanceNotFoundException: Self { .init(.ec2InstanceNotFoundException) }
    /// Unable to connect because the instance is not in a valid state.  Connecting to a stopped or terminated instance is not supported. If the instance is stopped,  start your instance, and try to connect again.
    public static var ec2InstanceStateInvalidException: Self { .init(.ec2InstanceStateInvalidException) }
    /// The instance type is not supported for connecting via the serial console. Only Nitro instance types are currently supported.
    public static var ec2InstanceTypeInvalidException: Self { .init(.ec2InstanceTypeInvalidException) }
    /// The instance is currently unavailable. Wait a few minutes and try again.
    public static var ec2InstanceUnavailableException: Self { .init(.ec2InstanceUnavailableException) }
    /// One of the parameters is not valid.
    public static var invalidArgsException: Self { .init(.invalidArgsException) }
    /// Your account is not authorized to use the EC2 Serial Console. To authorize your account, run the EnableSerialConsoleAccess API. For more information, see EnableSerialConsoleAccess in the Amazon EC2 API Reference.
    public static var serialConsoleAccessDisabledException: Self { .init(.serialConsoleAccessDisabledException) }
    /// The instance currently has 1 active serial console session. Only 1 session is supported at a time.
    public static var serialConsoleSessionLimitExceededException: Self { .init(.serialConsoleSessionLimitExceededException) }
    /// Unable to start a serial console session. Please try again.
    public static var serialConsoleSessionUnavailableException: Self { .init(.serialConsoleSessionUnavailableException) }
    /// Your instance's BIOS version is unsupported for serial console connection. Reboot your instance to update its BIOS, and then try again to connect.
    public static var serialConsoleSessionUnsupportedException: Self { .init(.serialConsoleSessionUnsupportedException) }
    /// The service encountered an error. Follow the instructions in the error message and try again.
    public static var serviceException: Self { .init(.serviceException) }
    /// The requests were made too frequently and have been throttled. Wait a while and try again.  To increase the limit on your request frequency, contact AWS Support.
    public static var throttlingException: Self { .init(.throttlingException) }
}

extension EC2InstanceConnectErrorType: Equatable {
    public static func == (lhs: EC2InstanceConnectErrorType, rhs: EC2InstanceConnectErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension EC2InstanceConnectErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
